//
//  UIWindow+ZXHierarchy.m
//  YiShangbao
//
//  Created by simon on 2017/4/24.
//  Copyright © 2017年 com.Microants. All rights reserved.
//

#import "UIWindow+ZXHierarchy.h"

@implementation UIWindow (ZXHierarchy)

/*
 <__NSArrayM 0x600000cd9560>(
 <UIWindow: 0x101f0a840; frame = (0 0; 393 852); gestureRecognizers = <NSArray: 0x600000c66490>; backgroundColor = <UIDynamicSystemColor: 0x600001749900; name = _windowBackgroundColor>; layer = <UIWindowLayer: 0x600000c65fb0>>,
 <UITextEffectsWindow: 0x10400b000; frame = (0 0; 393 852); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x600000c4e8e0>>
 )
 */

+ (nullable NSArray *)zx_windows
{
    NSArray *windows = nil;
    if (@available(iOS 13.0,*)) {
        NSSet <UIScene *>*connectedScenes = [UIApplication sharedApplication].connectedScenes;
        UIWindowScene *scene = nil;
        if (![UIApplication sharedApplication].supportsMultipleScenes) {
            scene = (UIWindowScene *)[[connectedScenes allObjects] firstObject];
        }else{
            for (UIWindowScene * windowScene in connectedScenes) {
                if (windowScene.activationState == UISceneActivationStateForegroundActive) {
                    scene = windowScene;
                }
            }
        }
        windows = scene.windows;
    }else{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        windows = UIApplication.sharedApplication.windows;
#pragma clang diagnostic pop
    }
    return windows;
}


+ (nullable UIWindow *)zx_mainWindow
{
    UIWindow *window = nil;
    if (@available(iOS 13.0,*)) {
        
        NSSet <UIScene *>*connectedScenes = [UIApplication sharedApplication].connectedScenes;
        UIWindowScene *scene = nil;
        if (![UIApplication sharedApplication].supportsMultipleScenes) {
            scene = (UIWindowScene *)[[connectedScenes allObjects] firstObject];
        }else{
            for (UIWindowScene * windowScene in connectedScenes) {
                if (windowScene.activationState == UISceneActivationStateForegroundActive) {
                    scene = windowScene;
                }
            }
        }
        id sceneDelegate = scene.delegate;
        if (sceneDelegate){
            if ([sceneDelegate respondsToSelector:@selector(setWindow:)])
            {
                window = [sceneDelegate window];
            }
        }
        else
        {
            window = [[[UIApplication sharedApplication] delegate] window];
        }
    }else{
        window = [[[UIApplication sharedApplication] delegate] window];
    }
    return window;
}


+ (nullable UIWindow *)zx_keyWindow{
    UIWindow *keyWindow = nil;
    if (@available(iOS 13.0,*)) {
        NSSet <UIScene *>*connectedScenes = [UIApplication sharedApplication].connectedScenes;
        UIWindowScene *scene = nil;
        if (![UIApplication sharedApplication].supportsMultipleScenes) {
            scene = (UIWindowScene *)[[connectedScenes allObjects] firstObject];
        }else{
            for (UIWindowScene * windowScene in connectedScenes) {
                if (windowScene.activationState == UISceneActivationStateForegroundActive) {
                    scene = windowScene;
                }
            }
        }
        if (@available(iOS 15.0, *)) {
            keyWindow = scene.keyWindow;
        } else {
            NSArray *windows = scene.windows;
            NSUInteger index = [windows indexOfObjectPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                UIWindow *window = (UIWindow *)obj;
                return window.isKeyWindow;
            }];
            if (index != NSNotFound) {
                keyWindow = [windows objectAtIndex:index];
            }
        }
    }else{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        keyWindow = [[UIApplication sharedApplication] keyWindow];
#pragma clang diagnostic pop
        
    }
    return  keyWindow;
}


///经过测试，textField响应的键盘window是这个。
+ (nullable UIWindow *)zx_remoteKeyboardWindow
{
    UIWindow *window = nil;
    NSArray *windows = [self zx_windows];
    NSUInteger index = [windows indexOfObjectPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UIWindow *window = (UIWindow *)obj;
        NSString *str = NSStringFromClass([window class]);
        return [str isEqualToString:@"UITextEffectsWindow"];
    }];
    if (index != NSNotFound) {
        window = [windows objectAtIndex:index];
    }
    return window;
}


+ (nullable UIWindow *)zx_frontVisibleWindow
{
    UIWindow *window = [UIWindow zx_remoteKeyboardWindow];
    if (window)
    {
        return window;
    }
    return [UIWindow zx_keyWindow];
}


/*
 键盘window的screen和keywindow的screen一样，windowScene也是同一个，所以不需要判断。
 其实倒过来的第一个window就是最上面的
 windows = {
     <UIWindow: 0x101f0a840; frame = (0 0; 393 852); gestureRecognizers = <NSArray: 0x600000c66490>; backgroundColor = <UIDynamicSystemColor: 0x600001749900; name = _windowBackgroundColor>; layer = <UIWindowLayer: 0x600000c65fb0>>;
     <UITextEffectsWindow: 0x10400b000; frame = (0 0; 393 852); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x600000c4e8e0>>;
 }
 
 po [windows[0]windowScene]
 <UIWindowScene: 0x10230b900; role: UIWindowSceneSessionRoleApplication; activationState: UISceneActivationStateForegroundActive> {
     session = <UISceneSession: 0x600001759cc0; persistentIdentifier: 62A11753-0D8E-410B-8032-3F19CA883B1A> {
         configuration = <UISceneConfiguration: 0x6000017d1680; name: 0x0>;
     };
     delegate = (nil);
     screen = <UIScreen: 0x102306960; bounds: {{0, 0}, {393, 852}}; mode: <UIScreenMode: 0x60000023e9a0; size = 1179.000000 x 2556.000000>>;
     windows = {
         <UIWindow: 0x101f0a840; frame = (0 0; 393 852); gestureRecognizers = <NSArray: 0x600000c66490>; backgroundColor = <UIDynamicSystemColor: 0x600001749900; name = _windowBackgroundColor>; layer = <UIWindowLayer: 0x600000c65fb0>>;
         <UITextEffectsWindow: 0x10400b000; frame = (0 0; 393 852); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x600000c4e8e0>>;
     }
 }
 
 
 (lldb) po [windows[1]windowScene]
 <UIWindowScene: 0x10230b900; role: UIWindowSceneSessionRoleApplication; activationState: UISceneActivationStateForegroundActive> {
     session = <UISceneSession: 0x600001759cc0; persistentIdentifier: 62A11753-0D8E-410B-8032-3F19CA883B1A> {
         configuration = <UISceneConfiguration: 0x6000017d1680; name: 0x0>;
     };
     delegate = (nil);
     screen = <UIScreen: 0x102306960; bounds: {{0, 0}, {393, 852}}; mode: <UIScreenMode: 0x60000023e9a0; size = 1179.000000 x 2556.000000>>;
     windows = {
         <UIWindow: 0x101f0a840; frame = (0 0; 393 852); gestureRecognizers = <NSArray: 0x600000c66490>; backgroundColor = <UIDynamicSystemColor: 0x600001749900; name = _windowBackgroundColor>; layer = <UIWindowLayer: 0x600000c65fb0>>;
         <UITextEffectsWindow: 0x10400b000; frame = (0 0; 393 852); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x600000c4e8e0>>;
     }
 }
 
 UIScreen.mainScreen
 <UIScreen: 0x102306960; bounds: {{0, 0}, {393, 852}}; mode: <UIScreenMode: 0x60000023e9a0; size = 1179.000000 x 2556.000000>>
 */

+ (nullable UIWindow *)zx_frontWindow
{
    NSArray *windows = [UIWindow zx_windows];
    NSEnumerator *frontToBackWindows = [windows reverseObjectEnumerator];
    for (UIWindow *window in frontToBackWindows)
    {
        BOOL windowIsVisible = !window.hidden && window.alpha > 0;
        BOOL windowLevelSupported = (window.windowLevel >= UIWindowLevelNormal);
        if(windowIsVisible && windowLevelSupported) {
            return window;
            break;
        }
    }
    return nil;
}


+ (nullable UIViewController *)zx_currentViewController{
    UIWindow *window =  [UIWindow zx_mainWindow];
    UIViewController *currentViewController = [window zx_topMostWindowController];
    if([currentViewController isKindOfClass:[UITabBarController class]])
    {
        //返回tabBarController的选中控制器
        if ([(UITabBarController *)currentViewController selectedViewController]) {
            currentViewController = [(UITabBarController *)currentViewController selectedViewController];
        }
        else
        {
            //如果当前没有选中的viewControoller，则返回tabBarController的第一个控制器
            UITabBarController *tabBarController = (UITabBarController *)currentViewController;
            currentViewController = [tabBarController.viewControllers firstObject];
        }
    }
    while ([currentViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)currentViewController topViewController])
        currentViewController = [(UINavigationController*)currentViewController topViewController];
    return currentViewController;
}

/*
 while循环就是循环结构的一种，当事先不知道循环该执行多少次，就要用到while循环
 当while循环主体有且只有一个语句时，可以将大括号省去。
 在while循环语句中只有一个判断条件，它可以是任何表达式。
 当判断条件的值为真，循环就会执行一次，再重复测试判断条件，执行循环主体，知道判断条件为假（false），才会跳离while循环。
 */
- (UIViewController *)zx_topMostWindowController
{
    UIViewController *topController = [self rootViewController];
    while ([topController presentedViewController])
    {
        topController = [topController presentedViewController];
    }
    //  Returning topMost ViewController
    return topController;
}



@end





